/*
 * Copyright (c) 2009 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.pyrogames.jme.extension;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import net.pyrogames.deled.geometry.DXSNode;
import net.pyrogames.deled.importer.DXSExtension;
import net.pyrogames.deled.math.DXSVector3f;

/**
 * Attachment points are essentially nodes that give a user
 * a lot more ease in attaching things such as submeshes (weapons)
 * or emitters (projectiles and particle meshes).
 * <p>
 * DeleD does not have an ideal "dummy object" that has a location
 * and a direction. Ideally, an attachment point should have both. For this
 * demonstration we will make an attachment point that just as a location. Our
 * DeleD object will be a cube, that will be extracted and made into an attachment
 * point node with its location the center of the cube.
 * <p>
 * This extension relies on objects to be named in a unique way for this
 * extension to identify the attachment point. By default:
 * <p>
 * A cube object should be named: "attp_XXX"
 * <p>
 * Where "attp_" is a unique prefix identifying the attachment point,
 * and "XXX" being its base name.
 * <p>
 * Users can change this prefix identifier for their own custom identifier.
 * <p>
 * Alternatively, users could use a single sided rectangle and use
 * its face normal as the up axis of the attachment point.
 * 
 * @author Nicholas Woodfield
 *
 */
public class AttachmentExtension implements DXSExtension {
	protected String prefix = "attp_";

	@Override
	public boolean executeExtension(DXSNode node, Element dxsElem) {
		//Perform a test to see if this has the attribute type "rectangle"
		String name = dxsElem.getAttribute("name");
		//Perform test to see if this has the identifier we're looking for
		if(name.startsWith(prefix)){
			//Parse vertices
			NodeList firstVertexList = dxsElem.getElementsByTagName("vertices");
			NodeList vertices = ((Element)firstVertexList.item(0)).getElementsByTagName("vertex");
			DXSVector3f[] vectors = new DXSVector3f[vertices.getLength()];
			for(int i = 0; i < vertices.getLength(); i++){
				Element vertex = (Element) vertices.item(i);
				float x = Float.parseFloat(vertex.getAttribute("x"));
				float y = Float.parseFloat(vertex.getAttribute("y"));
				float z = Float.parseFloat(vertex.getAttribute("z"));
				vectors[i] = new DXSVector3f(x,y,z,Integer.parseInt(vertex.getAttribute("id")));
			}
			//Create the node and attach it to the node
			DXSNode attachmentPoint = new DXSNode(name);
			attachmentPoint.setLocation(computeCenterFromPoints(vectors));
			node.attachChild(attachmentPoint);
			return true;
			}
		return false;
	}
	
	/**
	 * Customize the prefix notation for identifying
	 * 
	 * @param s
	 */
	public void setPrefix(String s){
		prefix = s;
	}
	
	private DXSVector3f computeCenterFromPoints(DXSVector3f[] points){
        if (points == null)
            return null;
        
        DXSVector3f center = new DXSVector3f();
        float minX = points[0].x;
        float minY = points[0].y;
        float minZ = points[0].z;
        float maxX = points[0].x;
        float maxY = points[0].y;
        float maxZ = points[0].z;
        
        for(int i = 1; i < points.length; i++){
        	if(points[i].x < minX){
        		minX = points[i].x;
        	} else if(points[i].x > maxX){
        		maxX = points[i].x;
        	}
        	
        	if(points[i].y < minY){
        		minY = points[i].y;
        	} else if(points[i].y > maxY){
        		maxY = points[i].y;
        	}
        	
        	if(points[i].z < minZ){
        		minZ = points[i].z;
        	} else if(points[i].z > maxZ){
        		maxZ = points[i].z;
        	}
        }
        
        center.set(minX + maxX, minY + maxY, minZ + maxZ);
        center.multLocal(.5f);
        System.out.println(center);
        return center;
	}

}
